
#include <string.h> 

#include "rtl876x.h"
#include "rtl876x_rcc.h"
#include "rtl876x_rtc.h" 
#include "rtl876x_nvic.h"

#include "iqw_module_clock.h"

#include "log.h"

#define LOG     LOG_INFO2

#define CLOCK_CMP_CHANNEL_IDX       0 
#define CLOCK_SOURCE_FREQ           32000
#define CLOCK_MINUTE_CHANNEL_IDX    1 



//static volatile uint32_t                m_ticks = 0; 

static uint32_t rtc_ticks = 0;
//static iqw_module_clock_cb_t            m_cb = NULL; 

static void io_init(void)
{
    // do nothings 
}

static void driver_init(void)
{
    RTC_DeInit();
    RTC_SetPrescaler( 0 ); 
    RTC_MaskINTConfig( RTC_INT_COMP0, ENABLE ); 
    RTC_INTConfig( RTC_INT_COMP0, DISABLE ); 
    
    
    NVIC_InitTypeDef nvicInitStruct;
    nvicInitStruct.NVIC_IRQChannel              = RTC_IRQn;
    nvicInitStruct.NVIC_IRQChannelPriority      = 3; 
    nvicInitStruct.NVIC_IRQChannelCmd           = ENABLE;
    NVIC_Init( &nvicInitStruct ); 
    
    RTC_SystemWakeupConfig( ENABLE );     
}

static void clock_start(void)
{
    uint32_t compare = (RTC_GetCounter() + CLOCK_SECOND_VALUE) & 0xFFFFFF; 
        
    RTC_SetCompValue( 0, compare );
    
    
    RTC_MaskINTConfig( RTC_INT_COMP0, DISABLE ); 
    RTC_INTConfig( RTC_INT_COMP0, ENABLE ); 
    RTC_NvCmd( ENABLE );
    RTC_RunCmd( ENABLE ); 
}

#if 0
void RTC_Handler(void)
{
    if( RTC_GetINTStatus( RTC_INT_COMP0) == SET ) 
    {
        uint32_t compare = (RTC_GetCompValue( 0 ) + CLOCK_SECOND_VALUE) & 0xFFFFFF;         
        RTC_SetCompValue( 0, compare ); 
        RTC_ClearCompINT( 0 );
//        LOG("count = %d, compare = %d", RTC_GetCounter(), RTC_GetCompValue(0) );
        rtc_ticks++;

        if( m_cb != NULL ) 
        {
            m_cb(); 
        }
    }

    if( RTC_GetINTStatus(RTC_INT_OVF) == SET ) 
    {
        RTC_ClearOverFlowINT();
    }
}
#endif
uint32_t iqw_module_rtc_get_tick_millsecond(void)
{
    uint32_t diff = ( RTC_GetCounter() - RTC_GetCompValue( CLOCK_CMP_CHANNEL_IDX ) ) & 0xFFFFFF;
    
    return (diff * 1000) / CLOCK_SECOND_VALUE;    
}
#if 0
uint32_t iqw_module_rtc_get_ticks(void)
{
    return RTC_GetCounter();
}
#endif
int iqw_module_rtc_check_timeout( uint32_t begin, uint32_t interval)
{
    uint32_t diff = (RTC_GetCounter() - begin) & 0xFFFFFF;
    return diff >= interval ;
}


void iqw_module_clock_init(void)
{
    io_init();
    
    driver_init(); 
    
    clock_start();
}

uint32_t iqw_module_clock_get_seconds(void)
{
    return rtc_ticks; 
}
/*
void iqw_module_clock_register_callback( iqw_module_clock_cb_t cb )
{
    m_cb = cb; 
}
*/
